import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { ChargeOrder } from 'src/entities/ChargeOrder';
import { ChargeOrderModelService } from 'src/model/charge-order-model/charge-order-model.service';
import { RedisService } from 'src/redis/redis.service';
import { ChargeOrderRealTimeInfo, ChargeOrderRealTimeInfocument } from 'src/schema/ChargeOrderRealTimeInfo.schema';
import ChargeOrderResult from 'src/type/ChargeOrderResult';
import { FindConditions, LessThan } from 'typeorm';

@Injectable()
export class ChargeOrderService {
    private chargingOrderKey = '';
    constructor(
        private chargeOrderModelService:ChargeOrderModelService,
        private redis:RedisService,
        private configService:ConfigService,

        @InjectModel(ChargeOrderRealTimeInfo.name) private chargeOrderRealTimeInfoModel: Model<ChargeOrderRealTimeInfocument>
    ) {
        this.chargingOrderKey = this.configService.get<string>('cacheKey.chargingOrder')
    }

    async page(query:Pagination, userId:number) {
        let where:FindConditions<ChargeOrder> = { userId }
        const lastId = query.lastKey || 0
        const pageSize = query.pageSize || 20

        if(query.lastId > 0) {
            where.userId = LessThan(lastId)
        }

        let rows:ChargeOrder[] = await this.chargeOrderModelService.find(where, null, 0, pageSize, {orderId : 'DESC'})

        return rows
    }

    async charging(userId:number) {
        const key = this.chargingOrderKey + userId
        let orderIds = await this.redis.call<number[]>('lrange', key, 0, -1)
        orderIds.push(901031)
        if(!orderIds || orderIds.length == 0) return null

        let orders:ChargeOrderResult[] = []
        let orderList = await this.chargeOrderModelService.find(orderIds.map(id => ({orderId : id})), ['userId', 'orderId', 'orderNo', 'status', 'deviceId', 'portNo', 'chargeAmount', 'strategyType'])
        orderIds.splice(0)
        if(orderList.length > 0) {
            orderList.forEach(order => {
                console.log(order.status)
                if(order.status != 1) {
                    this.redis.call('lrem', key, 0, order.orderId)
                }else {
                    orderIds.push(order.orderId)
                    orders.push(order)
                }
            })

            if(orderIds.length > 0) {
                let realTimeInfos = await this.chargeOrderRealTimeInfoModel.find({$or : orderIds.map(id => ({orderId : id}))}, {orderId : 1, lastData: 1})
                if(realTimeInfos) {
                    orders.forEach(order => {
                        for(let i = 0; i < realTimeInfos.length; i ++) {
                            if(order.orderId == realTimeInfos[i].orderId) {
                                order.realTimeInfo = realTimeInfos[i].lastData
                                realTimeInfos.splice(i, 0)
                                break
                            }
                        }
                    })
                }
            }
        }
    
        return orders
    }

    async chargingOne(orderId:number, userId:number) {
        let order:ChargeOrderResult = await this.chargeOrderModelService.findOne({ orderId }, ['userId', 'orderId', 'deviceId', 'portNo', 'chargeAmount', 'strategyType'])
        if(!order || order.userId != userId || order.status != 1) return null
        order.realTimeInfo = await this.chargeOrderRealTimeInfoModel.find({ orderId }, {lastData: 1})

        return order
    }
}
